<template>
	<div class="container" ref="container">
		<div class="zh-pagination">
			<span class="zh-pagination-total">共<span>{{total}}</span>条</span>
			<dropdown v-if="layouts.includes('pages')" :selectedValue="pageSize" :items="sizes"
				@selected="changePagesize"></dropdown>
			<!-- 上一页 -->
			<button class="btn-prev" v-if="layouts.includes('prev')" @click="selectNo>1&&goto(selectNo-1)"
				:disabled="selectNo===1">
				<i class="zh-iconfont zh-icon-left"></i>
			</button>
			<ul class="zh-page">
				<li @click="goto(item.pageNo)" v-for="(item,index) in pageNumbers" :key="index" :class="{
					background,
					'zh-iconfont':item.more,
					'zh-icon-shenglve':item.more,
					'active-selected':background&&selectNo===item.pageNo,
					selected:!background&&selectNo===item.pageNo,
				}">{{item.page?item.pageNo:""}}</li>
			</ul>
			<!-- 下一页 -->
			<button class="btn-next" v-if="layouts.includes('next')" @click="selectNo<pages&&goto(selectNo+1)"
				:disabled="selectNo===pages">
				<i class="zh-iconfont zh-icon-right"></i>
			</button>
			<div class="zh-editor">
				<span v-if="layouts.includes('goto')">前往</span>
				<input class="zh-input" v-model="pageNumber" @keypress="enterGoto" :class="{clickedPage:pageShow}"
					@click.stop="clickedPage" />
				<span v-if="layouts.includes('goto')">页</span>
			</div>
		</div>
	</div>
</template>

<script>
	import dropdown from '../dropdown/dropdown.vue';
	import {
		addEventListener,
		removeEventListener,
	} from "../event.js";

	function converToItems(arr) {
		return arr.map((c) => {
			return {
				value: c,
				name: `${c}`
			};
		});
	};
	export default {
		// 组件名称
		name: 'zh-pagination',
		// 组件参数 接收来自父组件的数据
		props: {
			// 是否可用
			disabled: Boolean,
			// 每页显示条数下拉框选项
			pageSizes: {
				type: Array,
				validator(value) {
					return value.length && value.every((c) => !isNaN(c));
				}
			},
			// 总条数
			total: {
				required: true,
				type: Number,
				validator(value) {
					return value > -1;
				}
			},
			// 每页显示条数
			pageSize: Number,
			// 显示页码数
			showPages: {
				type: Number,
				default: 7,
				validator(value) {
					return value >= 5 && value <= 21 && value % 2 === 1;
				},
			},
			// 默认每页显示条数
			defaultPagesize: Number,
			// 当前页
			pageIndex: {
				type: Number,
				default: 1,
				validator(value) {
					return value > 0;
				}
			},
			// 布局
			layouts: {
				type: Array,
				default () {
					return ['next', 'prev', 'pages', 'goto', 'info'];
				}
			},
			// 是否有背景色
			background: Boolean,
		},
		// 局部注册的组件
		components: {
			dropdown
		},
		// 组件状态值
		data() {
			return {
				// 向上 
				direction: "",
				pageShow: false,
				// 每页显示几个页码数
				showPage: 0,
				// 中间页码列表
				pageNumbers: [],
				// 总页数
				pages: 0,
				// 选中的页码
				selectNo: 1,
				// 每页显示条数
				_pageSize: 0,
				// 选择的页码
				pageNumber: "",
				sizes: converToItems([10, 20, 30, 50, 70]),
			}
		},
		mounted() {
			addEventListener(document, 'click', this.hide)
			this.calc();
		},
		beforeDestroy() {
			removeEventListener(document, "click", this.hide);
		},
		// 计算属性
		computed: {},
		// 侦听器
		watch: {
			//改变页码
			pageIndex(value) {
				this.selectNo = value;
				this.calc();
			},
			//每页显示条数
			pageSize(value) {
				this._pageSize = value;
				this.calc();
			},
		},
		// 组件方法
		methods: {
			// 点击任意位置，取消效果
			hide() {
				this.pageShow = false;
			},

			clickedPage() {
				this.pageShow = !this.pageShow;
			},
			// 更改每页显示条数
			changePagesize(obj) {
				this.$emit("update:pageSize", obj.value);
				this._pageSize = obj.value;
				this.calc();
				this.trigger();
			},
			// 回车跳转
			enterGoto(e) {
				e = e.keyCode || e.charCode;
				if (e === 13 && /\d+/.test(this.pageNumber)) {
					const number = Math.min(
						this.pages,
						Math.max(parseInt(this.pageNumber), 1)
					);
					number !== this.selectNo && (this.selectNo = number) && (this.calc() || this.trigger());
					this.pageNumber = "";
				}
			},
			// 跳转
			goto(pageNo) { // pageNo  页码
				// debugger
				console.log(pageNo)
				this.selectNo = pageNo;
				this.calc();
				this.trigger();
			},
			// 触发事件
			trigger() {
				this.$emit("changed", this.selectNo, this._pageSize);
			},
			// 计算
			calc() {
				// debugger
				this.$emit("update:pageIndex", this.selectNo);
				// 总页数=总页码/每页显示条数
				this.pages = parseInt(this.total / this._pageSize);
				// 判断   总条数/页码数  如果有余数   就加上
				if (this.total % this._pageSize > 0) {
					this.pages++; //有一种情况是多几条，所以要取模
				}
				// 初始化总页码
				this.pageNumbers.splice(0);
				if (this.pages < 1) {
					// 如果总页数小于1就没必要继续
					return;
				}
				const tempPages = [{
					page: true,
					pageNo: 1,
				}, ]; //临时存放页数
				this.selectNo = Math.min(this.selectNo, this.pages); // 选中的页数    最大不能超过总页数
				if (this.pages > 2) {
					// 中间要显示的页码数=中间的条数-初始值
					let showPages = Math.min(this.showPages - 2, this.pages - 2);
					// 平均数=总条数/2
					let middle = parseInt(showPages / 2);
					// 开始的值=当前选中的页码数-两边的平均数
					let start = Math.max(this.selectNo - middle, 2);
					// 结束值=当前选中的页码数+平均数     最大总页数-1
					let end = Math.min(this.selectNo + middle, this.pages - 1);
					// 差值
					let cha = showPages - (end - start + 1); //中间的条数=结束值-初始值+1
					// 如果初始值是2
					if (start === 2) {
						end += cha;
					} else {
						start -= cha;
					}
					if (start > 2) {
						tempPages.push({
							more: true,
							pageNo: start - 1
						});
					}
					while (start > 0 && start <= end) {
						tempPages.push({
							page: true,
							pageNo: start++,
						});
					}
					if (end < this.pages - 1) {
						tempPages.push({
							pageNo: end + 1,
							more: true,
						})
					}
					if (this.pages > 1) {
						tempPages.push({
							page: true,
							pageNo: this.pages,
						});
					}
				}
				this.pageNumbers.push(...tempPages);
			}
		},
		created() {
			if (this.pageSizes.length) {
				this._pageSize = this.pageSizes.some((c) => c === this.pageSize) ?
					this.pageSize :
					this.pageSizes[0];
				this.sizes = converToItems(this.pageSizes);
				console.log(this._pageSize);
			}
			this.selectNo = this.pageIndex;
			this.calc();
		}
	}
</script>

<style lang="scss" scoped>
	@import '../variable';

	// 边框高亮
	.clicked,
	.clickedPage {
		border: 1px solid $blue !important;
	}
	
	.selected {
		color: $blue;
		cursor: default;
	
		&:hover {
			color: $blue;
		}
	}

	.active {
		background-color: #f4f4f5;
		&:hover{
			color: $blue;
		}
		&-selected {
			background: $blue;
			color: white;
			cursor: default;
		
			&:hover {
				color: white;
			}
		}
	}

	// 最大的容器
	.container {
		position: relative;

		.zh-pagination {
			margin: 20px 0;
			height: 28px;
			line-height: 28px;
			display: flex;
			font-size: 13px;
			color: #606266;
			cursor: pointer;
			// z-index: 9999;

			.zh-pagination-total {
				margin-right: 10px;

				span {
					margin: 0 5px;
				}
			}

			.zh-select-box {
				position: relative;
				width: 100px;
				border: 1px solid #DCDFE6;
				padding: 5px;
				box-sizing: border-box;
				text-align: center;
				line-height: 1;
				border-radius: 3px;
				transition: all .3s;

				.icon {
					position: absolute;
					right: 5px;
					font-size: 14px;
					color: #C0C4CC;
					transition: transform .3s;
				}

				.icon[show] {
					transform: rotate(-180deg);
				}

				.zh-select-total {
					padding-right: 18px;
				}
			}

			.zh-select-box:hover {
				border: 1px solid $blue;
			}

			.btn-prev,
			.btn-next,
			.zh-page li {
				min-width: 32px;
				border-radius: 2px;
				margin: 0 5px;
			}

			// 禁用
			.btn-prev[disabled] {
				cursor: not-allowed;
			}

			// 上一页  下一页
			.btn-prev,
			.btn-next {
				border: none;
				outline: none;
				background-color: #FFFFFF;
				cursor: pointer;
			}

			.zh-page {
				list-style: none;
				padding: 0;
				margin: 0;
				display: flex;

				li {
					text-align: center;
					height: 28px;
					line-height: 28px;
					font-weight: 700;
				}

			}

			.zh-input {
				width: 50px;
			}

			.zh-editor {
				height: 28px;
				line-height: 28px;
				display: flex;
				width: 110px;

				.zh-input {
					height: 28px;
					line-height: 18px;
					outline: none;
					border: 1px solid #DCDFE6;
					border-radius: 4px;
					color: #606266;
					text-align: center;
					transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
					cursor: pointer;
					padding: 0 15px;
					box-sizing: border-box;
					margin: 0 5px;
				}

				.zh-input:hover {
					border: 1px solid #BBBBBB;
				}
			}

		}

	}
</style>
